home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Programming / MuManual / C_Sources / MuIndirectTest.c < prev    next >
C/C++ Source or Header  |  1999-07-11  |  9KB  |  243 lines

  1. /*************************************************
  2.  ** MuIndirectTest                              **
  3.  **                                             **
  4.  ** Use indirect page descriptors and fast      **
  5.  ** page swapping                               **
  6.  **                                             **
  7.  ** © 1999 THOR-Software                        **
  8.  ** Version 1.00        11.07.1999              **
  9.  *************************************************/
  10.  
  11. /// Includes
  12. #include <exec/types.h>
  13. #include <exec/memory.h>
  14. #include <dos/dos.h>
  15. #include <dos/dostags.h>
  16. #include <dos/dosextens.h>
  17.  
  18. /* MMU specific includes */
  19. #include <mmu/mmutags.h>
  20. #include <mmu/context.h>
  21. #include <mmu/descriptor.h>
  22.  
  23. #include <proto/exec.h>
  24. #include <proto/dos.h>
  25. #include <proto/mmu.h>
  26.  
  27. #include <string.h>
  28. ///
  29. /// Defines
  30.  
  31. /* This is the location we will remap accesses to. Should be
  32.    available on all systems. */
  33. #define TESTLOCATION 0x80000000
  34. ///
  35. /// Protos
  36.  
  37. /* prototyping */
  38.  
  39. long __saveds main(void);
  40. void MMUIndirectTest(void);
  41. ///
  42. /// Statics
  43.  
  44. /* Just the library bases we need */
  45. char version[]="$VER: MuIndirectTest 1.00 (11.7.99) ©THOR";
  46.  
  47. struct MMUBase *MMUBase;
  48. struct DosLibrary *DOSBase;
  49. struct ExecBase *SysBase;
  50. ///
  51.  
  52. /// main
  53. long __saveds main(void)
  54. {
  55. long err,rc;
  56.  
  57.         /* This program compiles without startup code, hence we have
  58.            to setup ourselfs */
  59.  
  60.         SysBase=*((struct ExecBase **)(4L));
  61.         rc=20;
  62.  
  63.         /* open the required libraries */
  64.  
  65.         if (DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",37)) {
  66.  
  67.                 if (MMUBase=(struct MMUBase *)OpenLibrary("mmu.library",0L)) {
  68.  
  69.                         err=ERROR_REQUIRED_ARG_MISSING;
  70.  
  71.                         /* Check for a valid MMU. The mmu.library will also
  72.                            open without! */
  73.  
  74.                         if (!GetMMUType()) {
  75.                                 Printf("MuFastRom requires a working MMU.\n");
  76.                                 err=10;
  77.                         } else {
  78.                                 /* Run the tests */
  79.                                 MMUIndirectTest();
  80.                                 err=0;
  81.                         }
  82.  
  83.                         /* Check for error codes. Everything below 64
  84.                            is considered to be a custom error and
  85.                            passed thru as primary result code. */
  86.                         if (err<64) {
  87.                                 rc=err;
  88.                                 err=0;
  89.                         } else {
  90.                                 PrintFault(err,"MuIndirectTest failed");
  91.                                 rc=10;
  92.                         }
  93.                         SetIoErr(err);
  94.  
  95.                         /* Shut down: Close libraries */
  96.                         CloseLibrary((struct Library *)MMUBase);
  97.                 } else PrintFault(ERROR_OBJECT_NOT_FOUND,"MuIndirectTest");
  98.                 CloseLibrary((struct Library *)DOSBase);
  99.         }
  100.  
  101.         return rc;
  102. }
  103. ///
  104. /// MMUIndirectTest
  105. void MMUIndirectTest(void)
  106. {
  107. struct MMUContext *ctx;
  108. ULONG pagesize,size;
  109. void *testpage[2],*physical[2];
  110. ULONG descriptor[2];
  111. ULONG *desmem,*desphysical;
  112. struct MinList *map;
  113. char *dummy;
  114. int i;
  115.  
  116.         /* This is the TRUE test, finally. */
  117.  
  118.         /* Get the public default context as template for the new
  119.            context */
  120.         Printf("Locating the default context...\n");
  121.         ctx=DefaultContext();
  122.  
  123.         pagesize=GetPageSize(ctx);
  124.  
  125.         Printf("Allocating the test pages...\n");
  126.         /* Allocate memory for the two pages */
  127.         if (testpage[0]=AllocAligned(pagesize,MEMF_PUBLIC,pagesize)) {
  128.          if (testpage[1]=AllocAligned(pagesize,MEMF_PUBLIC,pagesize)) {
  129.  
  130.           /* Get the physical addresses of the pages */
  131.           size=pagesize;
  132.           physical[0]=testpage[0];
  133.           physical[1]=testpage[1];
  134.  
  135.           /* We don't check here for errors. The pages are aligned correctly */
  136.           PhysicalLocation(ctx,physical,&size);
  137.           PhysicalLocation(ctx,physical+1,&size);
  138.  
  139.           Printf("Test pages allocated.\n"
  140.                  "Page 0 is at 0x%08lx, physical 0x%08lx,\n"
  141.                  "Page 1 is at 0x%08lx, physical 0x%08lx\n",
  142.                  testpage[0],physical[0],
  143.                  testpage[1],physical[1]);
  144.  
  145.           /* Allocate memory for the descriptors. AllocMem is good
  146.              enough here, we need only long word alignment */
  147.           Printf("Allocating memory for the descriptors.\n");
  148.           if (desmem=AllocMem(sizeof(ULONG),MEMF_PUBLIC)) {
  149.            desphysical=desmem;
  150.            size=sizeof(ULONG);
  151.  
  152.            /* Again, we need the TRUE physical location */
  153.            PhysicalLocation(ctx,(void **)(&desphysical),&size);
  154.  
  155.            Printf("Descriptor allocated.\n"
  156.                   "Indirect descriptor at 0x%08lx, physical 0x%08lx,\n",
  157.                   desmem,desphysical);
  158.  
  159.            Printf("Building the descriptors.\n");
  160.  
  161.            /* We use here "used, modified" descriptors to avoid
  162.               unnecessary MMU writebacks of descriptors we exchange
  163.               anyways. Copyback cache mode is turned on, but the
  164.               call might not set it if it is not available. However,
  165.               it will not fail in this case. */
  166.            descriptor[0]=BuildIndirect(ctx,(ULONG)(physical[0]),MAPP_USED|MAPP_MODIFIED|MAPP_COPYBACK);
  167.            descriptor[1]=BuildIndirect(ctx,(ULONG)(physical[1]),MAPP_USED|MAPP_MODIFIED|MAPP_COPYBACK);
  168.  
  169.            /* Check for errors */
  170.            if (descriptor[0]!=BAD_DESCRIPTOR) {
  171.             if (descriptor[1]!=BAD_DESCRIPTOR) {
  172.  
  173.                 Printf("Descriptors are build.\n"
  174.                        "Descriptor 0 is 0x%08lx,\n"
  175.                        "Descriptor 1 is 0x%08lx\n",
  176.                        descriptor[0],descriptor[1]);
  177.  
  178.                 /* Now modify the MMU tree to include the descriptors */
  179.                 Printf("Mirroring the memory at 0x%08lx to the first descriptor.\n",
  180.                        TESTLOCATION);
  181.  
  182.                 /* Write the first descriptor out to memory */
  183.                 SetIndirect(desphysical,TESTLOCATION,descriptor[0]);
  184.  
  185.                 /* Make a backup of the current MMU setup */
  186.                 if (map=GetMapping(ctx)) {
  187.                  if (SetProperties(ctx,MAPP_INDIRECT,~0,TESTLOCATION,pagesize,
  188.                                    MAPTAG_DESCRIPTOR,desphysical,TAG_DONE)) {
  189.  
  190.                   Printf("Building a new MMU tree.\n");
  191.                    if (RebuildTree(ctx)) {
  192.                         Printf("Running the tests.\n");
  193.                         /* Copy a string into the first and second page */
  194.                         strcpy((char *)testpage[0],"This is page 0.");
  195.                         strcpy((char *)testpage[1],"This is page 1.");
  196.  
  197.                         /* Now, VERY important! Since we access these
  198.                            data from elsewhere, we MUST flush the cache
  199.                            to make sure the data is really written out
  200.                            to memory. */
  201.                         CacheClearU();
  202.  
  203.                         /* Get a pointer to the test page */
  204.                         dummy=(char *)TESTLOCATION;
  205.  
  206.                         for(i=0;i<10;i++) {
  207.                                 Printf("%s\n",dummy);
  208.                                 /* now swap the pages, and print
  209.                                    a different string of the
  210.                                    same address... This is the magic.
  211.                                    The call below is very fast!*/
  212.                                 SetIndirect(desphysical,TESTLOCATION,descriptor[1]);
  213.                                 Printf("%s\n",dummy);
  214.                                 /* And back! */
  215.                                 SetIndirect(desphysical,TESTLOCATION,descriptor[0]);
  216.                         }
  217.                         Printf("Test done.\n");
  218.                    } else Printf("Failed to rebuild the MMU tree.\n");
  219.  
  220.                    if (!SetPropertiesMapping(ctx,map,TESTLOCATION,pagesize,~0)) {
  221.                         Printf("Fatal! Can't restore the altered page.\n");
  222.                    }
  223.                    if (!RebuildTree(ctx)) {
  224.                            Printf("Fatal! Can't restore the previous MMU tree!\n");
  225.                    }
  226.                  } else Printf("Failed to install the indirect descriptor.\n");
  227.                  ReleaseMapping(ctx,map);
  228.                 } else Printf("Failed to make a backup of the MMU map.\n");
  229.             } else Printf("Could not build descriptor 0.\n");
  230.            } else Printf("Could not build descriptor 1.\n");
  231.  
  232.            /* Release the descriptor */
  233.            FreeMem(desmem,sizeof(ULONG));
  234.           } else Printf("No memory for the indirect descriptor.\n");
  235.           FreeMem(testpage[1],pagesize);
  236.          } else Printf("No memory for the test page 1.\n");
  237.          FreeMem(testpage[0],pagesize);
  238.         } else Printf("No memory for the test page 0.\n");
  239.  
  240. }
  241. ///
  242.  
  243.